//
// File:        bitmap.cc
// Description: bitmap class implementation
// Authors:     Haris Wang (dynmiw@gmail.com)
//
// 

#include <cstdio>
#include <cstring>
#include <cassert>
#include <math.h>
#include <unistd.h>
#include <iostream>
#include "rm_internal.h"



bitmap::bitmap(int numBits, char * buf=NULL):size(numBits)
{
    NumChars = ceil(1.0 * size / 8);
    buffer = new char[NumChars];

    if(buf==NULL)
    {
        memset((void*)buffer, 0 , NumChars);
    }
    else
    {
        memcpy(buffer, buf, NumChars);
    }
    
}


RC bitmap::to_char_buf(char * buf, int len) const
{
    assert( buf!=NULL && len==NumChars );

    memcpy((void*)buf, buffer, len);
    return 0;
}


bitmap::~bitmap()
{
    delete [] buffer;
}


void bitmap::set(unsigned int bitNum=0-1, bool sign=0)
{
    assert( bitNum<=(size-1) );
    int byte, offset;
    
    // set given bit to 1/0
    if (bitNum!=0-1)
    {
        byte = bitNum/8;
        offset = bitNum%8;
        if(sign)
        {
            buffer[byte] |= ~(1<<offset);  
        }
        else
        {
            buffer[byte] &= ~(1<<offset);  
        }
        return;
    }

    // set all bits to 1/0
    for(bitNum=0; bitNum<size; bitNum++)
    {
        byte = bitNum/8;
        offset = bitNum%8;  
        if(sign)
        {
            buffer[byte] |= ~(1<<offset);  
        }
        else
        {
            buffer[byte] &= ~(1<<offset);  
        }
    }
    
}


RC bitmap::getSize() const
{
    return size;
}

bool bitmap::test(unsigned int bitNumber) const
{
    assert(bitNumber <= size-1);
    unsigned int byte = bitNumber>>8;
    unsigned int offset = bitNumber%8;

    return (buffer[byte] & (1<<offset));
}